<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>MBTI性格测试 | LinkSoul</title>
    <link rel="icon" href="https://etnor.xyz/images/5518d579-b233-47a5-a67d-816bbc22f807.PNG" type="image/png">
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap" rel="stylesheet">
    <style>
        :root {
            --primary: #6c5ce7;
            --secondary: #00b894;
            --accent: #fdcb6e;
            --danger: #e17055;
            --bg: #f6f8fb;
            --card-bg: #fff;
            --border: #e3e6eb;
            --text: #222;
            --text-light: #888;
            --radius: 18px;
            --shadow: 0 4px 24px 0 rgba(80,120,200,0.09);
            --transition: .22s cubic-bezier(.4,0,.2,1);
        }
        html, body {
            height: 100%;
            background: var(--bg);
        }
        body {
            font-family: 'Inter', 'Noto Sans SC', 'Segoe UI', Arial, sans-serif;
            color: var(--text);
            min-height: 100vh;
            margin: 0;
        }
        /* 顶部导航栏 */
        .navbar {
            width: 100%;
            background: linear-gradient(90deg, var(--primary) 0%, var(--secondary) 100%);
            color: #fff;
            box-shadow: 0 2px 12px #b2bec333;
            padding: 0;
            position: sticky;
            top: 0;
            z-index: 100;
        }
        .navbar-inner {
            max-width: 1200px;
            margin: 0 auto;
            display: flex;
            align-items: center;
            padding: 0.7rem 2rem;
        }
        .navbar-logo {
            width: 40px;
            height: 40px;
            border-radius: 50%;
            margin-right: 1rem;
            box-shadow: 0 2px 8px #dbeafe;
            background: #fff;
            object-fit: cover;
        }
        .navbar-title {
            font-size: 1.35rem;
            font-weight: 600;
            letter-spacing: 0.04em;
            flex: 1;
        }
        .navbar-link {
            color: #fff;
            text-decoration: underline;
            font-size: 1rem;
            margin-left: 1.5rem;
            opacity: 0.85;
            transition: opacity .2s;
        }
        .navbar-link:hover { opacity: 1; }

        /* 页面布局 */
        .main-layout {
            display: flex;
            max-width: 1200px;
            margin: 2.5rem auto 0 auto;
            min-height: 70vh;
            gap: 2.5rem;
            padding: 0 1.5rem;
        }
        /* 侧边栏 */
        .sidebar {
            width: 260px;
            background: var(--card-bg);
            border-radius: var(--radius);
            box-shadow: var(--shadow);
            padding: 2rem 1.2rem 1.5rem 1.2rem;
            display: flex;
            flex-direction: column;
            gap: 2.2rem;
            align-items: flex-start;
            min-width: 200px;
            max-height: 480px;
            position: sticky;
            top: 90px;
            align-self: flex-start;
            animation: fadeInCard .7s;
        }
        .sidebar .progress-label {
            font-size: 1.08rem;
            color: var(--primary);
            font-weight: 600;
            margin-bottom: 0.5rem;
        }
        .sidebar .progress-bar-wrap {
            width: 100%;
            background: #f1f2fa;
            border-radius: 8px;
            height: 8px;
            overflow: hidden;
            margin-bottom: 0.5rem;
        }
        .sidebar .progress-bar {
            height: 100%;
            background: linear-gradient(90deg, var(--primary) 60%, var(--secondary) 100%);
            width: 0;
            transition: width var(--transition);
        }
        .sidebar .tip-title {
            font-size: 1.08rem;
            font-weight: 600;
            color: var(--secondary);
            margin-bottom: 0.3rem;
        }
        .sidebar .tip-content {
            color: var(--text-light);
            font-size: 0.98rem;
            line-height: 1.7;
        }
        .sidebar .tip-list {
            margin: 0.7rem 0 0 0.2rem;
            padding: 0;
            list-style: disc inside;
            color: var(--accent);
            font-size: 0.97rem;
        }
        /* 主答题区 */
        .main-content {
            flex: 1;
            min-width: 0;
            display: flex;
            flex-direction: column;
            align-items: center;
        }
        .mbti-header {
            margin-bottom: 2.2rem;
            text-align: center;
        }
        .mbti-header h1 {
            font-size: 2.1rem;
            font-weight: 600;
            margin: 0 0 0.5rem 0;
            letter-spacing: 0.02em;
            color: var(--primary);
        }
        .mbti-header p {
            color: var(--text-light);
            font-size: 1.08rem;
            margin: 0;
        }
        .card {
            background: var(--card-bg);
            border-radius: var(--radius);
            box-shadow: var(--shadow);
            padding: 2.2rem 1.5rem 2.5rem 1.5rem;
            max-width: 480px;
            width: 100%;
            margin: 0 auto;
            display: flex;
            flex-direction: column;
            align-items: stretch;
            animation: fadeInCard .5s;
        }
        @keyframes fadeInCard {
            from { opacity: 0; transform: translateY(30px);}
            to { opacity: 1; transform: none;}
        }
        .question-title {
            font-size: 1.25rem;
            font-weight: 600;
            margin-bottom: 2.2rem;
            color: var(--text);
            min-height: 2.5em;
        }
        .options-list {
            display: flex;
            flex-direction: column;
            gap: 1.1rem;
        }
        .option-btn {
            background: #f1f2fa;
            border: 1.5px solid #f1f2fa;
            border-radius: 12px;
            padding: 1.1rem 1.2rem 1.1rem 3.2rem;
            font-size: 1.05rem;
            color: var(--text);
            cursor: pointer;
            transition:
                    background var(--transition),
                    border-color var(--transition),
                    box-shadow var(--transition),
                    color var(--transition);
            outline: none;
            text-align: left;
            position: relative;
            font-family: inherit;
            min-height: 2.5em;
        }
        .option-btn .option-index {
            position: absolute;
            left: 1.1rem;
            top: 50%;
            transform: translateY(-50%);
            width: 1.7em;
            height: 1.7em;
            background: var(--primary);
            color: #fff;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-weight: 600;
            font-size: 1.05em;
            box-shadow: 0 2px 8px #6c5ce722;
            transition: background .2s;
        }
        .option-btn.selected, .option-btn:active {
            background: var(--primary);
            color: #fff;
            border-color: var(--primary);
            box-shadow: 0 2px 12px #6c5ce722;
        }
        .option-btn.selected .option-index,
        .option-btn:active .option-index {
            background: var(--accent);
            color: var(--primary);
        }
        .option-btn:hover:not(.selected) {
            background: #eaf1ff;
            border-color: var(--primary);
        }
        .option-btn:focus-visible {
            border-color: var(--secondary);
            box-shadow: 0 0 0 2px #00b89444;
        }
        .loader {
            margin: 4rem auto 0 auto;
            text-align: center;
            color: var(--primary);
            font-size: 1.1rem;
            letter-spacing: 0.05em;
        }
        .loader:after {
            content: '';
            display: inline-block;
            width: 1.2em;
            height: 1.2em;
            border: 3px solid var(--primary);
            border-top: 3px solid transparent;
            border-radius: 50%;
            margin-left: 0.8em;
            animation: spin 1s linear infinite;
            vertical-align: middle;
        }
        @keyframes spin { to { transform: rotate(360deg);} }
        .error-card {
            color: var(--danger);
            text-align: center;
            margin-top: 3rem;
        }
        .error-card button {
            margin-top: 1.2rem;
            background: var(--primary);
            color: #fff;
            border: none;
            border-radius: 8px;
            padding: 0.7rem 1.5rem;
            font-size: 1rem;
            cursor: pointer;
            transition: background .2s;
        }
        .error-card button:hover {
            background: #2563eb;
        }
        /* 底部信息栏 */
        .footer {
            width: 100%;
            background: #f1f2fa;
            color: var(--text-light);
            text-align: center;
            padding: 2.2rem 1rem 1.2rem 1rem;
            font-size: 0.98rem;
            margin-top: 3rem;
            border-top: 1px solid #e3e6eb;
        }
        .footer a {
            color: var(--primary);
            text-decoration: none;
            margin: 0 0.7em;
            font-weight: 600;
            transition: color .2s;
        }
        .footer a:hover { color: var(--secondary);}
        @media (max-width: 1000px) {
            .main-layout { flex-direction: column; gap: 0; }
            .sidebar { display: none; }
        }
        @media (max-width: 600px) {
            .navbar-inner { padding: 0.7rem 0.7rem; }
            .main-layout { padding: 0 0.2rem; }
            .card { padding: 1.2rem 0.5rem 1.5rem 0.5rem; }
        }
    </style>
</head>
<body>
<!-- 顶部导航栏 -->
<nav class="navbar">
    <div class="navbar-inner">
        <img src="https://etnor.xyz/images/5518d579-b233-47a5-a67d-816bbc22f807.PNG" class="navbar-logo" alt="logo">
        <span class="navbar-title">MBTI性格测试</span>
        <a class="navbar-link" href="https://www.16personalities.com/zh" target="_blank">MBTI知识</a>
        <a class="navbar-link" href="mailto:hi@linksoul.cn">联系我们</a>
    </div>
</nav>
<div class="main-layout">
    <!-- 侧边栏 -->
    <aside class="sidebar">
        <div>
            <div class="progress-label">答题进度</div>
            <div class="progress-bar-wrap">
                <div class="progress-bar" id="sidebarProgressBar"></div>
            </div>
            <div id="sidebarProgressText" style="color:var(--text-light);font-size:0.97rem;">0/20</div>
        </div>
        <div>
            <div class="tip-title">温馨提示</div>
            <div class="tip-content">
                <ul class="tip-list">
                    <li>每题仅有一个最符合你的选项</li>
                    <li>请根据第一直觉作答</li>
                    <li>测试结果仅供参考</li>
                </ul>
            </div>
        </div>
        <div>
            <div class="tip-title">答题小贴士</div>
            <div class="tip-content">
                <span>如遇网络问题可刷新页面，答题数据会自动保存。</span>
            </div>
        </div>
    </aside>
    <!-- 主答题区 -->
    <main class="main-content">
        <div class="mbti-header">
            <h1>探索你的性格类型</h1>
            <p>20道精选问题，发现真实自我，了解最适合你的发展方向</p>
        </div>
        <div id="loader" class="loader" style="display:none;">加载题目中...</div>
        <div id="questionsContainer"></div>
    </main>
</div>
<!-- 底部信息栏 -->
<footer class="footer">
    <div>
        &copy; 2024 LinkSoul | <a href="https://etnor.xyz/" target="_blank">官网</a>
        <a href="https://www.16personalities.com/zh" target="_blank">MBTI介绍</a>
        <a href="mailto:hi@linksoul.cn">联系邮箱</a>
    </div>
    <div style="margin-top:0.5em;font-size:0.93em;">
        本测试仅供娱乐与自我探索，结果不作为专业心理诊断依据。
    </div>
</footer>
<script>
    let currentQuestion = 0;
    let answers = {};
    let questions = [];
    let requestId = null;
    const apiBaseUrl = '/api/mbti';

    const questionsContainer = document.getElementById('questionsContainer');
    const loader = document.getElementById('loader');
    // 侧边栏进度
    const sidebarProgressText = document.getElementById('sidebarProgressText');
    const sidebarProgressBar = document.getElementById('sidebarProgressBar');

    function detectPlatform() {
        const userAgent = navigator.userAgent;
        if (/android/i.test(userAgent)) return 'android';
        if (/iPad|iPhone|iPod/i.test(userAgent)) return 'ios';
        if (/Windows|Macintosh|Linux/.test(userAgent)) return 'web';
        return 'other';
    }

    async function loadQuestions() {
        try {
            showLoader();
            const platform = detectPlatform();
            const response = await fetch(`${apiBaseUrl}/questions`);
            if (!response.ok) throw new Error('网络响应不正常');
            const data = await response.json();
            questions = data.data || [];
            requestId = data.requestId;
            if (requestId && !window.location.search.includes(requestId)) {
                const newPath = `${window.location.pathname.replace(/\/$/, '')}/?requestId=${requestId}&from=${platform}`;
                window.history.replaceState(null, '', newPath);
            }
            if (questions.length === 0) throw new Error('没有获取到题目');
            hideLoader();
            showQuestion(currentQuestion);
            updateProgress();
        } catch (error) {
            showError('题目加载失败，请刷新页面重试');
        }
    }

    function showLoader() {
        loader.style.display = 'block';
        questionsContainer.innerHTML = '';
    }
    function hideLoader() {
        loader.style.display = 'none';
    }
    function showError(message) {
        questionsContainer.innerHTML = `
                <div class="card error-card">
                    <h3>${message}</h3>
                    <button onclick="location.reload()">重新加载</button>
                </div>
            `;
    }

    function showQuestion(index) {
        const question = questions[index];
        if (!question) return;
        questionsContainer.innerHTML = `
                <form class="card" id="questionForm" autocomplete="off" tabindex="0">
                    <div class="question-title">${question.questionText}</div>
                    <div class="options-list">
                        ${question.options.map((option, i) => `
                            <button type="button" class="option-btn"
                                data-question-id="${question.questionId}"
                                data-option-id="${option.optionId}"
                                aria-label="${option.optionText}">
                                <span class="option-index">${String.fromCharCode(65 + i)}</span>
                                ${option.optionText}
                            </button>
                        `).join('')}
                    </div>
                </form>
            `;
        setTimeout(() => {
            const form = document.getElementById('questionForm');
            if (form) form.focus();
        }, 80);
    }

    // 事件委托
    questionsContainer.addEventListener('click', function(e) {
        if (e.target.classList.contains('option-btn') || e.target.closest('.option-btn')) {
            const btn = e.target.classList.contains('option-btn') ? e.target : e.target.closest('.option-btn');
            selectOption(btn);
        }
    });
    // 键盘可操作性
    questionsContainer.addEventListener('keydown', function(e) {
        if (e.target.classList.contains('option-btn') && (e.key === 'Enter' || e.key === ' ')) {
            e.preventDefault();
            selectOption(e.target);
        }
    });

    function selectOption(button) {
        const questionId = button.dataset.questionId;
        const optionId = button.dataset.optionId;
        button.parentElement.querySelectorAll('.option-btn').forEach(btn => btn.classList.remove('selected'));
        button.classList.add('selected');
        answers[questionId] = optionId;
        setTimeout(() => {
            if (currentQuestion < questions.length - 1) {
                currentQuestion++;
                showQuestion(currentQuestion);
                updateProgress();
            } else {
                submitAnswers();
            }
        }, 350);
    }

    function updateProgress() {
        const total = questions.length || 20;
        const progress = (currentQuestion + 1) / total * 100;
        // 侧边栏
        sidebarProgressBar.style.width = `${progress}%`;
        sidebarProgressText.textContent = `${currentQuestion + 1}/${total}`;
    }

    async function submitAnswers() {
        try {
            showLoader();
            const urlParams = new URLSearchParams(window.location.search);
            const urlRequestId = urlParams.get('requestId');
            const response = await fetch(`${apiBaseUrl}/submit?requestId=${urlRequestId || requestId}`, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({
                    userAnswers: answers,
                    requestId: requestId,
                    timestamp: Date.now()
                })
            });
            if (!response.ok) throw new Error('提交失败');
            const result = await response.json();
            window.location.href = `/result.html?requestId=${urlRequestId}`;
        } catch (error) {
            showError('结果提交失败，请稍后重试');
        }
    }

    document.addEventListener('DOMContentLoaded', loadQuestions);
</script>
</body>
</html>